package com.platform.modules.wallet.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.platform.common.constant.AppConstants;
import com.platform.common.utils.redis.RedisUtils;
import com.platform.common.web.service.impl.BaseServiceImpl;
import com.platform.modules.chat.domain.ChatUser;
import com.platform.modules.chat.service.ChatUserService;
import com.platform.modules.wallet.dao.WalletAccountDao;
import com.platform.modules.wallet.domain.Wallet;
import com.platform.modules.wallet.domain.WalletAccount;
import com.platform.modules.wallet.domain.WalletTransfer;
import com.platform.modules.wallet.enums.AccountStatusEnum;
import com.platform.modules.wallet.enums.AccountTypeEnum;
import com.platform.modules.wallet.service.WalletAccountService;
import com.platform.modules.wallet.service.WalletService;
import com.platform.modules.wallet.service.WalletTransferService;
import com.platform.modules.wallet.vo.AccountVo01;
import com.platform.modules.wallet.vo.AccountVo02;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

@Slf4j
@Service("chatAccountService")
public class WalletAccountServiceImpl extends BaseServiceImpl<WalletAccount> implements WalletAccountService {


    @Resource
    private WalletAccountDao walletAccountDao;
    @Resource
    private WalletService walletService;
    @Autowired
    public void setBaseDao() {
        super.setBaseDao(walletAccountDao);
    }
    @Autowired
    private RedisUtils redisUtils;
    @Resource
    private ChatUserService userService;
    @Resource
    private WalletTransferService transferService;

    @Override
    public WalletAccount createRecord(AccountVo01 accountVo) {
        return createRecord(accountVo, false);
    }

    @Override
    public WalletAccount createRecord(AccountVo01 accountVo, boolean negative) {

        WalletAccount bean = getBean();
        bean.setOtherId(accountVo.getOtherId());

        if (negative) {//是否负数
            bean.setAmount(-accountVo.getAmount());
        } else {
            bean.setAmount(accountVo.getAmount());
        }

        bean.setType(accountVo.getType());
        bean.setUserId(accountVo.getUserId());
        bean.setPrivateKey(bean.getKey());
        WalletAccount walletAccount = new WalletAccount().selectOne(new LambdaQueryWrapper<WalletAccount>()
                .eq(WalletAccount::getOtherId, bean.getOtherId())
                .eq(WalletAccount::getType, bean.getType()));
        if (ObjectUtil.isEmpty(walletAccount)) {
            this.add(bean);
        }
        return bean;
    }

    @Override
    public void successRecord(Long id) {
        WalletAccount account = findById(id);
        account.setBalance(walletService.getBalance(account.getUserId()));
        account.setStatus(AccountStatusEnum.SUCCESS);
        account.setSuccessTime(DateUtil.date());
        account.setPrivateKey(account.getKey());
        updateById(account);

        String todayKey = AppConstants.WALLET_ACCOUNT_BALANCE + account.getUserId();
        if (redisUtils.hasKey(todayKey)) redisUtils.delete(todayKey);
    }

    @Override
    public List<AccountVo02> queryByUserId(Long userId, int page) {

        if (page < 1) page = 1;

        IPage<WalletAccount> iPage = new Page(page, 20);//参数一是当前页，参数二是每页个数

        iPage = new WalletAccount().selectPage(iPage,
                new LambdaQueryWrapper<WalletAccount>()
                        .eq(WalletAccount::getUserId, userId)
                        .ge(WalletAccount::getCreateTime, DateUtil.offsetHour(DateUtil.date(), -5))
                        .orderByDesc(WalletAccount::getId));

        List<AccountVo02> list = Convert.convert(new TypeReference<List<AccountVo02>>() {}, iPage.getRecords());

        list.forEach(e->{
            if (AccountTypeEnum.TRANSFER_IN.equals(e.getType())){
                WalletTransfer in = transferService.getById(e.getOtherId());
                ChatUser fromUser = userService.getById(in.getFromId());
                if (ObjectUtil.isNotEmpty(fromUser))e.setNickName(fromUser.getNickName());
            }else if (AccountTypeEnum.TRANSFER_OUT.equals(e.getType())){
                WalletTransfer out = transferService.getById(e.getOtherId());
                ChatUser toUser = userService.getById(out.getToId());
                if (ObjectUtil.isNotEmpty(toUser))e.setNickName(toUser.getNickName());
            }
        });

        return list;
    }

    @Override
    public List<WalletAccount> queryYesterday(Long userId) {

        String yesterday = DateUtil.formatDate(DateUtil.yesterday());

        return new WalletAccount().selectList(
                new LambdaQueryWrapper<WalletAccount>()
                        .eq(WalletAccount::getUserId, userId)
                        .eq(WalletAccount::getCreateDate, yesterday)
        );
    }

    @Override
    public List<WalletAccount> queryToday(Long userId) {

        Date date = DateUtil.date();
        String format = DateUtil.format(date, "yyyy-MM-dd");

        return new WalletAccount().selectList(
                new LambdaQueryWrapper<WalletAccount>()
                        .eq(WalletAccount::getUserId, userId)
                        .eq(WalletAccount::getCreateDate, format));
    }

    @Override
    public Integer queryYesterDaySum(Long userId) {
        return walletAccountDao.queryYesterDaySum(userId, DateUtil.formatDate(DateUtil.yesterday()));
    }

    @Override
    public Integer queryTodaySum(Long userId) {
        return walletAccountDao.queryTodaySum(userId, DateUtil.today());
    }

    @Override
    public Integer querySumAll() {
        return walletAccountDao.querySumAll(DateUtil.today());
    }

    @Override
    public Integer clearRecord(String beforeToday) {
        return walletAccountDao.clearRecord(beforeToday);
    }

    @Override
    public IPage<WalletAccount> queryPage(Integer paeg, Integer size) {

        IPage<WalletAccount> page = new Page(paeg, size);//参数一是当前页，参数二是每页个数

        page = new WalletAccount().selectPage(page,
                new LambdaQueryWrapper<WalletAccount>());

        return page;
    }

    private WalletAccount getBean() {
        WalletAccount account = new WalletAccount();
        account.setStatus(AccountStatusEnum.INIT);
        account.setCreateTime(DateUtil.date());
        account.setCreateDate(DateUtil.date());
        return account;
    }
}
